package com.supermap.wzhy.module.user.service;

import com.supermap.wzhy.common.service.BaseService;
import com.supermap.wzhy.data.cons.CMacroMetaType;
import com.supermap.wzhy.data.cons.CMicroMetaType;
import com.supermap.wzhy.data.cons.CPowerDataType;
import com.supermap.wzhy.data.cons.CStatus;
import com.supermap.wzhy.entity.*;
import com.supermap.wzhy.module.data.dao.MicroIdenmetaDao;
import com.supermap.wzhy.module.data.dao.MicroTablemetaDao;
import com.supermap.wzhy.module.user.dao.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据权限服务层
 *
 * @author Created by W.Qiong on 14-10-20.
 */
@Service
public class DataPowerService extends BaseService {
    /** 用户数据权限dao */
    @Autowired
    DataUserpowerDao dataUserpowerDao;

    /** 用户数据权限dao */
    @Autowired
    DataRolePowerDao dataRolePowerDao;

    /** 用户角色dao */
    @Autowired
    UserRoleDao userRoleDao;

    /** 用户相关dao */
    @Autowired
    UserDao userDao;

    /** 基层对象元数据信息dao */
    @Autowired
    MicroTablemetaDao microTablemetaDao;

    /** 基本指标配置信息dao */
    @Autowired
    MicroIdenmetaDao microIdenmetaDao;


    /**
     * 获取用户某一项权限 包括用户所属角色下的权限(指定类型下的所有权限,去重复)
     *
     * @param userid
     *            用户id
     * @param dataType
     *            dataType 数据类型（基层或者综合）
     * @param roleids
     *            角色（一个或者多个）id
     * @return 权限(指定类型下的所有权限,去重复) {dataid:'dataid'}
     */
    public Map getUserPowerByType(int userid, int dataType, int[] roleids) {
        Map<Integer, String> map = new HashMap<>();

        // 通过指定用户id和数据类型查询用户数据权限列表
        List<TDataUserpower> userPowers = dataUserpowerDao.findByDataType(
                userid, dataType);
        for (TDataUserpower userpower : userPowers) {
            int dataid = userpower.getDataId();
            if (map.containsKey(dataid)) {
                continue;
            }
            map.put(dataid, dataid + "");
        }

        // 查询指定角色（一个或者多个）id和数据类型的数据权限列表
        List<TDataRolepower> rolesPowers = null;
        if (roleids != null && roleids.length > 0) {
            rolesPowers = dataRolePowerDao.findByDataType(roleids, dataType);
        }
        if (rolesPowers != null) {
            for (TDataRolepower rolepower : rolesPowers) {
                int dataid = rolepower.getDataId();
                if (map.containsKey(dataid)) {
                    continue;
                }
                TDataUserpower userpower = new TDataUserpower();
                userpower.setDataId(dataid);
                userpower.setDataType(rolepower.getDataType());
                userPowers.add(userpower);
                map.put(dataid, dataid + "");
            }
        }
        return map;
    }

    /**
     * 获取某个角色下的某类数据权限
     *
     * @param roleid
     *            角色id
     * @param dataType
     *            dataType 数据类型（基层或者综合）
     *
     * @return 权限(指定类型下的所有权限,去重复) {dataid:'dataid'}
     */
    public Map getRolePowerByType(int roleid, int dataType) {
        List<TDataRolepower> rolesPowers = new ArrayList<>();
        int[] roleids = new int[1];
        roleids[0] = roleid;
        rolesPowers = dataRolePowerDao.findByDataType(roleids, dataType);
        Map<Integer, String> map = new HashMap<>();
        for (TDataRolepower datapower : rolesPowers) {
            int dataId = datapower.getDataId();
            if (map.containsKey(dataId)) {
                continue;
            }
            map.put(dataId, dataId + "");
        }
        return map;
    }

    /**
     * 设置用户的权限
     *
     * @param userid
     *            用户的id
     * @param dataids
     *            一个或者多个dataid
     * @param parid
     *            父节点id(若包含'_'分隔符，代表设置的权限为调查对象指标的权限，否则为调查对象的权限)
     * @return 是否设置成功
     */
    public boolean setUserPowers(int userid, int[] dataids, String parid) {
        String[] selSplit = parid.split("_");
        int len = selSplit.length;
        if (selSplit[len - 1].equals("micro")) {
            return setUserMicroPowers(userid, dataids, parid);
        } else if (selSplit[len - 1].equals("major")) {
            return setUserMicroMajorPowers(userid, dataids, parid);
        } else {
            return setUserMacroPowers(userid, dataids, parid);
        }
    }

    /**
     * 设置用户基层数据权限
     *
     * @param userid
     *            用户id
     * @param dataids
     *            数据(data)(一个或者多个)id
     * @param parid
     *            父节点id(若包含'_'分隔符，代表设置的权限为调查对象指标的权限，否则为调查对象的权限)
     * @return 是否设置成功
     */
    public boolean setUserMicroPowers(int userid, int[] dataids, String parid) {
        String[] selSplit = parid.split("_");
        int len = selSplit.length;
        TUsers user = userDao.findOne(userid);
        if (null == user) {
            return false;
        }

        // 设置调查对象的权限
        if (len < 2) {
            List<TDataUserpower> dataPowers = dataUserpowerDao.findByDataType(
                    userid, CPowerDataType.MICRO_SUERVER);
            dataUserpowerDao.delete(dataPowers);
            if (dataids.length == 0) {
                return true;
            }
            List<TMicroTablemeta> tablemetas = microTablemetaDao
                    .findByMitmids(dataids);
            dataPowers = new ArrayList<>();
            for (TMicroTablemeta tablemeta : tablemetas) {
                TDataUserpower userpower = new TDataUserpower();
                userpower.setTUsers(user);
                userpower.setDataId(tablemeta.getMitmid());
                userpower.setDataType(CPowerDataType.MICRO_SUERVER);
                userpower.setStatus(CStatus.READY);
                dataPowers.add(userpower);

            }
            List<TDataUserpower> re = dataUserpowerDao.save(dataPowers);

            return re.size() > 0 ? true : false;

            // 设置调查对象指标的权限
        } else {
            // 调查对象id
            int mitmid = Integer.parseInt(selSplit[0]);
            List<TMicroIdenmeta> idenmetas = microIdenmetaDao
                    .findObjectIdens(mitmid);
            int[] delDataIds = new int[idenmetas.size()];
            for (int i = 0; i < idenmetas.size(); i++) {
                delDataIds[i] = idenmetas.get(i).getMiimid();
            }
            List<TDataUserpower> dataPowers = dataUserpowerDao.findByDataIds(
                    userid, CPowerDataType.MICRO_IDE, delDataIds);
            dataUserpowerDao.delete(dataPowers);
            dataPowers = new ArrayList<>();
            if (dataids.length == 0) {
                return true;
            }
            idenmetas = microIdenmetaDao.findByids(dataids);
            for (TMicroIdenmeta idenmeta : idenmetas) {
                TDataUserpower userpower = new TDataUserpower();
                userpower.setTUsers(user);
                userpower.setDataId(idenmeta.getMiimid());
                userpower.setDataType(CPowerDataType.MICRO_IDE);
                userpower.setStatus(CStatus.READY);
                dataPowers.add(userpower);
            }
            List<TDataUserpower> re = dataUserpowerDao.save(dataPowers);

            return re.size() > 0 ? true : false;
        }// end if (len < 2) else
    }

    /**
     * 设置基层专业权限 控制到数据记录
     *
     * @param userid
     *            用户id
     * @param dataids
     *            数据(data)(一个或者多个)id
     * @param parid
     *            父节点id(必须包含'_marjor')
     * @return 是否设置成功
     */
    public boolean setUserMicroMajorPowers(int userid, int[] dataids,
                                           String parid) {
        TUsers user = userDao.findOne(userid);
        if (null == user) {
            return false;
        }
        String[] split = parid.split("_");
        String type = split[split.length - 1];
        if (!type.equals("major")) {
            return false;
        }
        List<TDataUserpower> dataPowers = dataUserpowerDao.findByDataType(
                userid, CPowerDataType.MICRO_MAJOR);
        dataUserpowerDao.delete(dataPowers);
        if (dataids == null || dataids.length == 0) {
            return true;
        }
        dataPowers = new ArrayList<>();
        for (int id : dataids) {
            TDataUserpower userpower = new TDataUserpower();
            userpower.setTUsers(user);
            userpower.setDataId(id);
            userpower.setDataType(CPowerDataType.MICRO_MAJOR);
            userpower.setStatus(CStatus.READY);
            dataPowers.add(userpower);

        }
        List<TDataUserpower> re = dataUserpowerDao.save(dataPowers);

        return re.size() > 0 ? true : false;
    }

    /**
     * 设置用户综合数据权限
     *
     * @param userid
     *            用户id
     * @param dataids
     *            数据(data)(一个或者多个)id
     * @param parid
     *            父节点id(若包含'_'分隔符，包含'_macro'或'_level'或'_catalog'或'_table')
     * @return 是否设置成功
     */
    public boolean setUserMacroPowers(int userid, int[] dataids, String parid) {
        TUsers user = userDao.findOne(userid);
        if (null == user) {
            return false;
        }
        String[] selSplit = parid.split("_");
        int len = selSplit.length;
        if (len < 1)
            return false;

        List<Map<String, String>> reList = new ArrayList<>();

//        List<TDataUserpower> re = dataUserpowerDao.save(dataPowers);

//        return re.size() > 0 ? true : false;

        return  false ;
    }

    /**
     * 设置角色权限
     *
     * @param roleid
     *            指定角色权限id
     * @param dataids
     *            一个或者多个dataid
     * @param parid
     *            父节点id(若包含'_'分隔符，代表设置的权限为调查对象指标的权限，否则为调查对象的权限)
     * @return 是否设置成功
     */
    public boolean setRolePowers(int roleid, int[] dataids, String parid) {
        String[] selSplit = parid.split("_");
        int len = selSplit.length;
        // 基层数据权限
        if (selSplit[len - 1].equals("micro")) {
            return setRoleMicroPowers(roleid, dataids, parid);
        } else if (selSplit[len - 1].equals("major")) {
            return setRoleMicroMajorPowers(roleid, dataids, parid);
        } else {
            return setRoleMacroPowers(roleid, dataids, parid);
        }
    }

    /**
     * 设置角色基层数据权限
     *
     * @param roleid
     *            指定角色权限id
     * @param dataids
     *            数据(data)(一个或者多个)id
     * @param parid
     *            父节点id(若包含'_'分隔符，代表设置的权限为调查对象指标的权限，否则为调查对象的权限)
     * @return 是否设置成功
     */
    public boolean setRoleMicroPowers(int roleid, int[] dataids, String parid) {
        String[] selSplit = parid.split("_");
        int len = selSplit.length;
        TUserrole role = userRoleDao.findOne(roleid);
        if (null == role) {
            return false;
        }
        int[] roleids = new int[1];
        roleids[0] = roleid;
        if (len < 2) {
            // 设置调查对象的权限
            List<TDataRolepower> dataPowers = dataRolePowerDao.findByDataType(
                    roleids, CPowerDataType.MICRO_SUERVER);
            dataRolePowerDao.delete(dataPowers);
            if (dataids.length == 0) {
                return true;
            }
            List<TMicroTablemeta> tablemetas = microTablemetaDao
                    .findByMitmids(dataids);
            dataPowers = new ArrayList<>();
            for (TMicroTablemeta tablemeta : tablemetas) {
                TDataRolepower rolepower = new TDataRolepower();
                rolepower.setTUserrole(role);
                rolepower.setDataId(tablemeta.getMitmid());
                rolepower.setDataType(CPowerDataType.MICRO_SUERVER);
                rolepower.setStatus(CStatus.READY);
                dataPowers.add(rolepower);
            }
            List<TDataRolepower> re = dataRolePowerDao.save(dataPowers);
            return re.size() > 0 ? true : false;

        } else {
            // 设置调查对象指标的权限
            int mitmid = Integer.parseInt(selSplit[0]);// 调查对象id
            List<TMicroIdenmeta> idenmetas = microIdenmetaDao
                    .findObjectIdens(mitmid);
            int[] delDataIds = new int[idenmetas.size()];
            for (int i = 0; i < idenmetas.size(); i++) {
                delDataIds[i] = idenmetas.get(i).getMiimid();
            }
            List<TDataRolepower> dataPowers = dataRolePowerDao.findByDataIds(
                    roleid, CPowerDataType.MICRO_IDE, delDataIds);
            dataRolePowerDao.delete(dataPowers);
            if (dataids.length == 0) {
                return true;
            }
            dataPowers = new ArrayList<>();
            idenmetas = microIdenmetaDao.findByids(dataids);
            for (TMicroIdenmeta idenmeta : idenmetas) {
                TDataRolepower rolepower = new TDataRolepower();
                rolepower.setTUserrole(role);
                rolepower.setDataId(idenmeta.getMiimid());
                rolepower.setDataType(CPowerDataType.MICRO_IDE);
                rolepower.setStatus(CStatus.READY);
                dataPowers.add(rolepower);
            }
            List<TDataRolepower> re = dataRolePowerDao.save(dataPowers);
            return re.size() > 0 ? true : false;
        }

    }

    /**
     * 设置基层角色权限 控制到数据记录
     *
     * @param roleid
     *            指定的角色id
     * @param dataids
     *            数据(data)(一个或者多个)id
     * @param parid
     *            父节点id(必须包含'_marjor')
     * @return 是否设置成功
     */
    public boolean setRoleMicroMajorPowers(int roleid, int[] dataids,
                                           String parid) {
        String[] split = parid.split("_");
        String type = split[split.length - 1];
        if (!type.equals("major")) {
            return false;
        }
        TUserrole role = userRoleDao.findOne(roleid);
        if (null == role) {
            return false;
        }
        int[] roleids = new int[1];
        roleids[0] = roleid;

        List<TDataRolepower> dataPowers = dataRolePowerDao.findByDataType(
                roleids, CPowerDataType.MICRO_MAJOR);
        dataRolePowerDao.delete(dataPowers);
        if (dataids.length == 0) {
            return true;
        }
        dataPowers = new ArrayList<>();
        for (int id : dataids) {
            TDataRolepower rolepower = new TDataRolepower();
            rolepower.setTUserrole(role);
            rolepower.setDataId(id);
            rolepower.setDataType(CPowerDataType.MICRO_MAJOR);
            rolepower.setStatus(CStatus.READY);
            dataPowers.add(rolepower);
        }
        List<TDataRolepower> re = dataRolePowerDao.save(dataPowers);
        return re.size() > 0 ? true : false;
    }

    /**
     * 设置角色综合数据权限
     *
     * @param roleid
     *            指定角色id
     * @param dataids
     *            数据(data)(一个或者多个)id
     * @param parid
     *            父节点id(若包含'_'分隔符，包含'_macro'或'_level'或'_catalog'或'_table')
     * @return 是否设置成功
     */
    public boolean setRoleMacroPowers(int roleid, int[] dataids, String parid) {
        TUserrole role = userRoleDao.findOne(roleid);
        if (null == role) {
            return false;
        }
        String[] selSplit = parid.split("_");
        int len = selSplit.length;
//        List<TDataRolepower> re = dataRolePowerDao.save(dataPowers);
//
//        return re.size() > 0 ? true : false;
        return  false ;
    }


    /**
     * 添加某一项数据权限 创建数据对象时
     *
     * @param user
     *            用户对象
     * @param dataIds
     *            数据(data)(一个或者多个)id
     * @param dataType
     *            数据类型 基层/综合(由CPowerDataTypechang中常量指定)
     * @return 是否添加成功
     */
    public boolean addUserPowers(TUsers user, int[] dataIds, int dataType) {
        if (null == user) {
            return false;
        }
        int userid = Integer.parseInt(user.getUserid()+"");
        // 检查是否存在 存在则删除
        delUserPowers(userid, dataIds, dataType);

        switch (dataType) {
            case CPowerDataType.MICRO_SUERVER:
            case CPowerDataType.MICRO_IDE:
                return addUserMicroPowers(user, dataIds, dataType);
            case CPowerDataType.MACRO:
//                return addUserMacroPowers(user, dataIds, dataType);
                return  false ;
            default:
                return false;
        }
    }

    /**
     * 添加指定用户下的基层数据权限（调查对象或基层指标）
     *
     * @param user
     *            用户对象
     * @param dataIds
     *            数据(data)(一个或者多个)id
     * @param dataType
     *            基层数据类型(由CPowerDataType.MICRO_SUERVER或CPowerDataType.MICRO_IDE)
     * @return 是否添加成功
     */
    private boolean addUserMicroPowers(TUsers user, int[] dataIds, int dataType) {
        List<TDataUserpower> dataPowers = new ArrayList<>();
        if (dataType == CPowerDataType.MICRO_SUERVER) {
            List<TMicroTablemeta> tablemetas = microTablemetaDao
                    .findByMitmids(dataIds);
            for (TMicroTablemeta tablemeta : tablemetas) {
                if (tablemeta.getMicmetaType() != CMicroMetaType.OBJECT_TYPE) {
                    continue;
                }
                TDataUserpower userpower = new TDataUserpower();
                userpower.setTUsers(user);
                userpower.setDataId(tablemeta.getMitmid());
                userpower.setDataType(dataType);
                userpower.setStatus(CStatus.READY);
                dataPowers.add(userpower);
            }
            List<TDataUserpower> re = dataUserpowerDao.save(dataPowers);
            return re.size() > 0 ? true : false;
        } else {
            StringBuilder sqlBuilder = new StringBuilder();
            sqlBuilder.append("select miimid from t_micro_idenmeta where miimid in (");
            for(int i = 0; i < dataIds.length; i++) {
                if((i + 1) % 1000 == 0) { //数据库in (...)最多支持1000个数据
                    sqlBuilder = new StringBuilder(sqlBuilder.substring(0, sqlBuilder.length() - 1) + ")");
                    sqlBuilder.append(" or miimid in(");
                }
                sqlBuilder.append(dataIds[i] + ",");
            }
            String sql = sqlBuilder.substring(0, sqlBuilder.length() - 1) + ")";
            List<Object> miimids = microIdenmetaDao.query(sql);

            //for (Object[] miimid : miimids) {
            for(int i = 0; i < miimids.size(); i++) {
                Object obj = miimids.get(i);
                TDataUserpower userpower = new TDataUserpower();
                userpower.setTUsers(user);
                userpower.setDataId(Integer.valueOf(obj.toString()));
                userpower.setDataType(dataType);
                userpower.setStatus(CStatus.READY);
                dataPowers.add(userpower);
            }
            /*List<TMicroIdenmeta> idenmetas = microIdenmetaDao.findByids(dataIds);//基层对象的所有指标
            for (TMicroIdenmeta idenmeta : idenmetas) {
                TDataUserpower userpower = new TDataUserpower();
                userpower.setTUsers(user);
                userpower.setDataId(idenmeta.getMiimid());
                userpower.setDataType(dataType);
                userpower.setStatus(CStatus.READY);
                dataPowers.add(userpower);
            }*/
            List<TDataUserpower> re = dataUserpowerDao.save(dataPowers);
            return re.size() > 0 ? true : false;
        }
    }


    /**
     *
     * 删除指定用户和数据类型下的指定数据(data)(一个或者多个)id的权限（ 调查对象或者指标、综合表）
     *
     * @param userid
     *            用户对象
     * @param dataIds
     *            数据(data)(一个或者多个)id
     * @param dataType
     *            综合数据类型(由CPowerDataType.MACRO)
     * @return
     */
    public boolean delUserPowers(int userid, int[] dataIds, int dataType) {
        if (dataIds == null || dataIds.length < 1) {
            return false;
        }
        String sql = "delete from t_data_userpower t where t.status=1 and t.data_Type=" + dataType + " and t.data_Id in (";
        for(int i = 0; i < dataIds.length; i++) {
            if((i + 1) % 1000 == 0) { //数据库in (...)最多支持1000个数据
                sql = sql.substring(0, sql.length() - 1) + ")";
                sql += " or t.data_Id in(";
            }
            sql += dataIds[i] + ",";
        }
        sql = sql.substring(0, sql.length() - 1) + ")";
        dataUserpowerDao.executeBySql(sql);
        return true;
    }
}
